(function (fruit, undefined) {
    var UNDEFINED = 'undefined';
    var expando = 'fruit' + (-new Date),
        uid = 0,
        dataCache = {},
        getCache = function (inElement, uid, name) {
            var objId = inElement[uid] || {};
            if (typeof name == UNDEFINED) {
                return objId;
            }
            return objId[name];
        },
        setCache = function (inElement, uid, name, value) {
            inElement[uid] = inElement[uid] || {};
            inElement[uid][name] = value;
        };
    var cache = {
        data:function (inElement, name, value) {
            var method = (typeof value !== UNDEFINED) ? cache.setData : cache.getData;
            return method(inElement, name, value);
        },
        getGlobalCache:function () {
            return dataCache;
        },
        setData:function (inElement, name, value) {
            if (inElement.nodeType) {
                var id = inElement[expando] = inElement[expando] || ++uid;
                return setCache(dataCache, id, name, value);
            } else {
                return setCache(inElement, expando, name, value);
            }
        },
        getData:function (inElement, name) {
            if (inElement.nodeType) {
                var id = inElement[expando] = inElement[expando] || ++uid;
                return getCache(dataCache, id, name);
            } else {
                return getCache(inElement, expando, name);
            }
        },
        removeData:function (inElement, name) {
            if (typeof name == UNDEFINED) {
                //delete all
                if (inElement.nodeType) {
                    delete dataCache[inElement[expando]];
                    inElement.removeAttribute(expando);
                } else {
                    delete inElement[expando];
                }
            } else {
                //delete by name
                if (inElement.nodeType) {
                    delete dataCache[inElement[expando]][name];
                } else {
                    delete inElement[expando][name];
                }
            }
        }
    };
    fruit.cache = cache;
})(fruit, undefined);